package com.koron.order.defect.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.github.pagehelper.PageInfo;
import com.koron.bean.base.Response;
import com.koron.bean.query.PageQuery;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.order.defect.bean.dto.DefectDTO;
import com.koron.order.defect.bean.dto.DefectEquipmentDto;
import com.koron.order.defect.bean.dto.SzlsDefectDto;
import com.koron.order.defect.bean.po.DefectBean;
import com.koron.order.defect.bean.po.DefectStatus;
import com.koron.order.defect.bean.query.DefectEquipmentQuery;
import com.koron.order.defect.bean.query.DefectQuery;
import com.koron.order.defect.bean.vo.DefectDetailVo;
import com.koron.order.defect.bean.vo.DefectVO;
import com.koron.order.defect.service.DefectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;

/**
 * @ClassName OrderController
 * @description
 * @Author zhouj
 * @Date 2021/9/1 11:26
 */
@Slf4j
@RequestMapping("/defect/")
@RestController
@Api(tags = "缺陷工单")
public class DefectController {

    @Autowired
    DefectService defectService;

    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    @PostMapping("saveOrUpdate")
    @ApiOperation(value = "新增或保存缺陷工单")
    public Response<DefectBean> saveOrUpdate(@RequestBody DefectDTO defectDTO) {
        //在这里判断一下 工单的状态,如果状态不是新建,草稿则不能保存
        //缺陷工单在设备管理单位领导时可以修改保存

//        verityStatus(defectDTO.getId(), DefectStatus.DRAFT.getStatus());
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "saveOrUpdate", DefectBean.class, defectDTO));
    }

    @ApiIgnore
    @PostMapping("add")
    @ApiOperation(value = "新增缺陷工单")
    public Response<Integer> add(DefectBean defectBean) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "saveOrUpdate", Integer.class, defectBean));
    }

    @PutMapping("save")
    @ApiOperation(value = "保存缺陷工单")
    public Response<Integer> update(DefectBean defectBean) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "update", Integer.class, defectBean));
    }

    @DeleteMapping("delete")
    @ApiOperation(value = "删除缺陷工单")
    public Response<Integer> delete(@RequestParam String id) {
        if (StringUtils.isEmpty(id)) {
            return Response.fail("id不能为空");
        }
        List<String> list = new ArrayList<>();
        list.add(id);
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "delete", Integer.class, list));
    }

    @DeleteMapping("deleteList")
    @ApiOperation(value = "删除缺陷工单")
    public Response<Integer> delete(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Response.fail("id不能为空");
        }
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "delete", Integer.class, ids));
    }


    @ApiOperation(value = "根据id查询")
    @GetMapping("queryById")
    public Response<DefectDetailVo> queryById(String id) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "queryById", DefectDetailVo.class, id));
    }

    @ApiOperation(value = "查询不分页列表")
    @GetMapping("queryList")
    public Response<List> queryList(DefectQuery query) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "queryList", List.class, query));
    }

    /*
      1、本单位用户能看到的数据范围：工单的设备管理单位在用户的组织权限之内的数据
      2、外单位用户能看到的数据范围：工单的作业单位在用户的组织权限之内的数据
    */
    @ApiOperation(value = "查询列表")
    @GetMapping("queryDefectVoList")
    public Response<PageInfo<DefectVO>> queryDefectVoList(DefectQuery query, PageQuery pageQuery) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "queryDefectVoList", PageInfo.class, query, pageQuery));
    }



    @ApiOperation(value = "数字孪生水光接口")
    @GetMapping("lightWaterQueryDefectByYear")
    public Response<List<SzlsDefectDto>> lightWaterQueryDefectByYear(SzlsDefectDto dto) {
        cn.hutool.core.lang.Assert.isFalse(ObjectUtil.isNull(dto.getStartTime()), "开始统计时间不能为空");
        cn.hutool.core.lang.Assert.isFalse(ObjectUtil.isNull(dto.getEndTime()), "结束统计时间不能为空");
        cn.hutool.core.lang.Assert.isFalse(StrUtil.isBlank(dto.getEquipmentId()), "设备标识不能为空");
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "lightWaterQueryDefectByYear", List.class, dto));
    }

    @ApiOperation(value = "提交")
    @GetMapping("submitDefect")
    public Response<Integer> submitDefect(String orderId, String status) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "submitDefect", Integer.class, orderId, status));
    }

    public void verityStatus(String orderId, String... orderStatus) {
        //在这里判断一下 工单的状态,如果状态不符合,则不能保存
        if (StringUtils.isEmpty(orderId)) {
            return;
        }
        Response<DefectDetailVo> response = queryById(orderId);
        DefectDetailVo data = response.getData();
        // 特定用户可以在归档之后修改执行信息
        if (orderStatus.length == 1){
            Assert.isTrue(Objects.isNull(data) || orderStatus[0].equals(data.getStatus()), "当前工单状态:" + DefectStatus.getDefectStatus(data.getStatus()).getDesc() + ",请重新打开");
        }else{
            Assert.isTrue(Objects.isNull(data) || Arrays.asList(orderStatus).indexOf(data.getStatus()) > -1, "当前工单状态:" + DefectStatus.getDefectStatus(data.getStatus()).getDesc() + ",请重新打开");
        }
    }

    @ApiOperation(value = "查询设备的缺陷次数")
    @PostMapping("/queryEquipmentDefectNums")
    public Response<List<DefectEquipmentDto>> queryEquipmentDefectNums(@RequestBody List<DefectEquipmentQuery> defectEquipmentQueryList) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "queryEquipmentDefectNums", List.class, defectEquipmentQueryList));
    }

    @ApiOperation(value = "待处理工单手动激活")
    @GetMapping("activePending")
    public Response<Integer> activePending(String orderId) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "activePending", Integer.class, orderId));
    }

    @ApiOperation(value = "待处理工单自动激活")
    @GetMapping("activePendingAuto")
    public Response<Integer> activePendingAuto(String currDs) {
        return Response.ok(ADOConnection.runTask(currDs, defectService, "activePendingAuto", Integer.class, currDs));
    }

    @ApiOperation(value = "单个作废工单")
    @DeleteMapping("deprecated")
    public Response<String> deprecated(String orderId) {
        Assert.isTrue(StringUtils.isNotEmpty(orderId));
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "deprecated", String.class, orderId));
    }

    @ApiOperation(value = "批量作废工单")
    @DeleteMapping("deprecatedBatch")
    public Response<String> deprecatedBatch(@RequestParam("orderIds") List<String> orderIds) {
        Assert.isTrue(CollectionUtils.isNotEmpty(orderIds));
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "deprecatedBatch", String.class, orderIds));
    }

    @SneakyThrows
    @ApiOperation(value = "导出缺陷工单", notes = "根据条件导出查询出的所有数据")
    @GetMapping("export")
    public void exportFile(HttpServletResponse response, DefectQuery query,PageQuery pageQuery) {
        PageInfo pageInfo = ADOConnection.runTask(getCurrDs(), defectService, "queryDefectVoList", PageInfo.class, query, pageQuery);
        Long total = pageInfo.getTotal();
        pageQuery.setPageSize(total.intValue());
        pageInfo = ADOConnection.runTask(getCurrDs(), defectService, "queryDefectVoList", PageInfo.class, query, pageQuery);
        List<DefectVO>defectVOList = (List<DefectVO>) pageInfo.getList();
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("缺陷工单", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), DefectVO.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet("缺陷工单")
                .doWrite(defectVOList);
    }


    @ApiOperation(value = "工单统计-消缺率统计", notes = "消缺率统计")
    @GetMapping("getRateOfDefect")
    public Response<Map> getRateOfDefect(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        Map<String,Object> result = ADOConnection.runTask(getCurrDs(), defectService, "getRateOfDefect", Map.class, startTime,endTime);
        return Response.ok(result);
    }

    @ApiOperation(value = "工单统计-消缺率及时率统计", notes = "消缺率及时率统计")
    @GetMapping("getRateImmediateOfDefect")
    public Response<Map> getRateImmediateOfDefect(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        Map<String,Object> result = ADOConnection.runTask(getCurrDs(), defectService, "getRateImmediateOfDefect", Map.class, startTime,endTime);
        return Response.ok(result);
    }

    @ApiOperation(value = "信息话平台建设系统-缺陷管理统计", notes = "消缺率eliminationRate，消缺及时率eliminationTimelyRate，当月缺陷数defectTotal")
    @GetMapping("rateOfDefect/gcxxh")
    public Response<Map> rateOfDefect(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        Map<String,Object> result = ADOConnection.runTask("water_02", defectService, "rateOfDefect", Map.class, startTime,endTime);
        return Response.ok(result);
    }


    @ApiOperation(value = "缺陷工单统计")
    @GetMapping("staDefect")
    public Response<Map> staDefect(@RequestParam(value = "startTime",required = false) String startTime, @RequestParam(value = "endTime", required = false) String endTime){
        return Response.ok(ADOConnection.runTask("water_02",defectService,"staDefect", Map.class, startTime, endTime));
    }


    @ApiOperation(value = "获取工单关键字引用次数")
    @GetMapping("getDefectStock")
    public Response<List> getDefectStock(){
        return Response.ok(ADOConnection.runTask(getCurrDs(), defectService, "getDefectStock", List.class));
    }

}
